<script setup lang="ts">
  import { fileUpload } from '@/api/upload'
  import { HMessage, HMessageBox } from '@/components/common/message'
  import { useCodeUpdateWorkDrawingService } from '@/services/module/code/useCode'
  import { UploadFile, UploadRawFile } from 'element-plus'
  import { debounce } from 'lodash'
  import { computed, PropType, ref, watch } from 'vue'
  import fileIcon from '@/assets/image/modules/code/detail-work-drawing.svg'

  const { updateForm, updateLoading, save, resetUpdateForm } = useCodeUpdateWorkDrawingService()

  defineOptions({
    name: 'WorkDrawingList',
  })

  const props = defineProps({
    codeDetail: {
      type: Object as PropType<SnCodeDetailAPIResponse.SnCodeDetail>,
      required: true,
    },
  })

  const emits = defineEmits<{
    (e: 'update'): void
  }>()

  const fileUploading = ref(false)

  const cadFileList = ref<Array<UploadRawFile>>([])
  const encryptionCertificateFileList = ref<Array<UploadRawFile>>([])
  const backupPackageFileList = ref<Array<UploadRawFile>>([])

  const fileNames = computed(() => {
    return {
      cadList: props.codeDetail.cadUrlList.map((file) => file.split('/').pop() || ''),
      encryptionCertificateList: props.codeDetail.keywordUrlList.map(
        (file) => file.split('/').pop() || '',
      ),
      backupPackageList: props.codeDetail.bfFileUrlList.map((file) => file.split('/').pop() || ''),
    }
  })

  const handleUploadFile = async (
    uploadType: 'cad' | 'encryptionCertificate' | 'backupPackage',
    file: UploadFile,
  ) => {
    if (file.raw) {
      const { cadUrlList, keywordUrlList, bfFileUrlList } = updateForm.value
      switch (uploadType) {
        case 'cad':
          if (cadFileList.value.length + cadUrlList.length >= 20) {
            HMessageBox.error('CAD文件最多上传20个')
          } else {
            cadFileList.value.push(file.raw)
          }
          break
        case 'encryptionCertificate':
          if (encryptionCertificateFileList.value.length + keywordUrlList.length >= 20) {
            HMessageBox.error('加密证书最多上传20个')
          } else {
            encryptionCertificateFileList.value.push(file.raw)
          }
          break
        case 'backupPackage':
          if (backupPackageFileList.value.length + bfFileUrlList.length >= 20) {
            HMessageBox.error('备份包最多上传20个')
          } else {
            backupPackageFileList.value.push(file.raw)
          }
          break
      }

      submit()
    }
  }

  /**
   * 提交方法
   * 加上防抖，是因为：
   * el-upload 组件的 on-change 事件会多次触发，导致多次提交
   */
  const submit = debounce(async () => {
    fileUploading.value = true
    if (cadFileList.value.length >= 1) {
      const res = await fileUpload(cadFileList.value)
      if (res.data.code === 20000) {
        updateForm.value.cadUrlList = [...res.data.data.rows, ...updateForm.value.cadUrlList]
      }
    }

    if (encryptionCertificateFileList.value.length >= 1) {
      const res = await fileUpload(encryptionCertificateFileList.value)
      if (res.data.code === 20000) {
        updateForm.value.keywordUrlList = [
          ...res.data.data.rows,
          ...updateForm.value.keywordUrlList,
        ]
      }
    }

    if (backupPackageFileList.value.length >= 1) {
      const res = await fileUpload(backupPackageFileList.value)
      if (res.data.code === 20000) {
        updateForm.value.bfFileUrlList = [...res.data.data.rows, ...updateForm.value.bfFileUrlList]
      }
    }
    fileUploading.value = false
    const res = await save()
    if (res) {
      if (res.code === 20000) {
        resetUpdateForm()
        emits('update')
        HMessage.success('操作成功')
        cadFileList.value.length = 0
        encryptionCertificateFileList.value.length = 0
        backupPackageFileList.value.length = 0
        return
      }

      HMessageBox.error(res.message)
      return
    }

    HMessageBox.error('删除失败，请稍候重试')
  }, 1000)

  const handleFileDel = (
    uploadType: 'cad' | 'encryptionCertificate' | 'backupPackage',
    fileIndex: number,
  ) => {
    switch (uploadType) {
      case 'cad':
        cadFileList.value.splice(fileIndex, 1)
        updateForm.value.cadUrlList.splice(fileIndex, 1)
        break
      case 'encryptionCertificate':
        encryptionCertificateFileList.value.splice(fileIndex, 1)
        updateForm.value.keywordUrlList.splice(fileIndex, 1)
        break
      case 'backupPackage':
        backupPackageFileList.value.splice(fileIndex, 1)
        updateForm.value.bfFileUrlList.splice(fileIndex, 1)
        break
    }

    submit()
  }

  const handleFileDelAll = (uploadType: 'cad' | 'encryptionCertificate' | 'backupPackage') => {
    switch (uploadType) {
      case 'cad':
        cadFileList.value = []
        updateForm.value.cadUrlList = []
        break
      case 'encryptionCertificate':
        encryptionCertificateFileList.value = []
        updateForm.value.keywordUrlList = []
        break
      case 'backupPackage':
        backupPackageFileList.value = []
        updateForm.value.bfFileUrlList = []
        break
    }

    submit()
  }

  const handleDownloadFile = (
    uploadType: 'cad' | 'encryptionCertificate' | 'backupPackage',
    fileIndex: number,
  ) => {
    let fileUrl = ''
    switch (uploadType) {
      case 'cad':
        fileUrl = updateForm.value.cadUrlList[fileIndex]
        break
      case 'encryptionCertificate':
        fileUrl = updateForm.value.keywordUrlList[fileIndex]
        break
      case 'backupPackage':
        fileUrl = updateForm.value.bfFileUrlList[fileIndex]
        break
    }

    const aEle = document.createElement('a')
    aEle.setAttribute('href', fileUrl)
    aEle.setAttribute('download', '')
    aEle.click()
  }

  watch(
    () => props.codeDetail,
    () => {
      updateForm.value = {
        id: props.codeDetail.id,
        cadUrlList: props.codeDetail.cadUrlList || [],
        keywordUrlList: props.codeDetail.keywordUrlList || [],
        bfFileUrlList: props.codeDetail.bfFileUrlList || [],
      }
    },
    { deep: true, immediate: true },
  )
</script>

<template>
  <div v-loading="fileUploading || updateLoading" class="work-drawing-list">
    <div class="cad work-drawing-item">
      <div class="title">
        <div class="text">CAD格式图纸文件</div>
        <el-upload
          :auto-upload="false"
          :on-change="(file: UploadFile) => handleUploadFile('cad', file)"
          :show-file-list="false"
          :multiple="true"
        >
          <h-plain-button :height="22" :padding-lr="8"> 上传 </h-plain-button>
        </el-upload>
        <h-plain-button :height="22" :padding-lr="8" type="error" @click="handleFileDelAll('cad')">
          删除全部
        </h-plain-button>
      </div>
      <div class="file-list">
        <div
          v-for="(fileName, fileNameIndex) in fileNames.cadList"
          :key="fileNameIndex"
          class="file"
        >
          <img class="file-icon" :src="fileIcon" alt="工图" />
          <el-tooltip effect="dark" :content="fileName" placement="top">
            <div class="text" :data-text="fileName">{{ fileName }}</div>
          </el-tooltip>
          <i
            class="iconfont icon-icon-mianxing_fuzhi_xiazai"
            @click="handleDownloadFile('cad', fileNameIndex)"
          ></i>
          <i class="iconfont icon-shanchu2" @click="handleFileDel('cad', fileNameIndex)"></i>
        </div>
      </div>
    </div>
    <div class="encryption-certificate work-drawing-item">
      <div class="title">
        <div class="text">加密证书</div>
        <el-upload
          :auto-upload="false"
          :on-change="(file: UploadFile) => handleUploadFile('encryptionCertificate', file)"
          :show-file-list="false"
          :multiple="true"
        >
          <h-plain-button :height="22" :padding-lr="8"> 上传 </h-plain-button>
        </el-upload>
        <h-plain-button
          :height="22"
          :padding-lr="8"
          type="error"
          @click="handleFileDelAll('encryptionCertificate')"
        >
          删除全部
        </h-plain-button>
      </div>
      <div class="file-list">
        <div
          v-for="(fileName, fileNameIndex) in fileNames.encryptionCertificateList"
          :key="fileNameIndex"
          class="file"
        >
          <img class="file-icon" :src="fileIcon" alt="工图" />
          <el-tooltip effect="dark" :content="fileName" placement="top">
            <div class="text" :data-text="fileName">{{ fileName }}</div>
          </el-tooltip>
          <i
            class="iconfont icon-icon-mianxing_fuzhi_xiazai"
            @click="handleDownloadFile('encryptionCertificate', fileNameIndex)"
          ></i>
          <i
            class="iconfont icon-shanchu2"
            @click="handleFileDel('encryptionCertificate', fileNameIndex)"
          ></i>
        </div>
      </div>
    </div>
    <div class="backup-package work-drawing-item">
      <div class="title">
        <div class="text">备份包</div>
        <el-upload
          :auto-upload="false"
          :on-change="(file: UploadFile) => handleUploadFile('backupPackage', file)"
          :show-file-list="false"
          :multiple="true"
        >
          <h-plain-button :height="22" :padding-lr="8"> 上传 </h-plain-button>
        </el-upload>
        <h-plain-button
          :height="22"
          :padding-lr="8"
          type="error"
          @click="handleFileDelAll('backupPackage')"
        >
          删除全部
        </h-plain-button>
      </div>
      <div class="file-list">
        <div
          v-for="(fileName, fileNameIndex) in fileNames.backupPackageList"
          :key="fileNameIndex"
          class="file"
        >
          <img class="file-icon" :src="fileIcon" alt="工图" />
          <el-tooltip effect="dark" :content="fileName" placement="top">
            <div class="text" :data-text="fileName">{{ fileName }}</div>
          </el-tooltip>
          <i
            class="iconfont icon-icon-mianxing_fuzhi_xiazai"
            @click="handleDownloadFile('backupPackage', fileNameIndex)"
          ></i>
          <i
            class="iconfont icon-shanchu2"
            @click="handleFileDel('backupPackage', fileNameIndex)"
          ></i>
        </div>
      </div>
    </div>
  </div>
</template>

<style scoped lang="scss">
  .work-drawing-list {
    width: 100%;
    height: 100%;
    display: flex;
    flex-direction: column;
    row-gap: 24px;
    overflow: auto;

    .work-drawing-item {
      // flex: 1;
      // height: 0;
      display: flex;
      flex-direction: column;
      row-gap: 8px;

      .title {
        display: flex;
        align-items: center;
        column-gap: 8px;
        font-size: 16px;
        font-weight: bold;
      }

      .file-list {
        // flex: 1;
        // height: 0;
        display: flex;
        flex-wrap: wrap;
        column-gap: 24px;
        row-gap: 16px;
        overflow: auto;

        .file {
          display: flex;
          align-items: center;
          column-gap: 8px;
          border: 1px solid #e5e5e5;
          padding: 12px;
          border-radius: 4px;

          .file-icon {
            width: 24px;
            height: 24px;
          }

          .text {
            position: relative;
            display: inline-block;
            font-size: 14px;
            width: 200px;
            text-overflow: ellipsis;
            overflow: hidden;
            white-space: nowrap;
            cursor: pointer;

            &:hover::after {
              content: attr(data-text); /* 通过 data-text 属性获取完整内容 */
              position: absolute;
              top: 100%; /* 显示在元素下方 */
              left: 0;
              background: #fff;
              border: 1px solid #ddd;
              padding: 8px 12px;
              border-radius: 4px;
              box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
              z-index: 1000;
              white-space: normal; /* 允许换行 */
              width: max-content; /* 宽度根据内容自动扩展 */
              max-width: 300px; /* 避免提示框过宽 */
            }
          }

          .icon-icon-mianxing_fuzhi_xiazai {
            font-size: 24px;
            color: #007aff;
            cursor: pointer;
          }

          .icon-shanchu2 {
            font-size: 16px;
            color: #f56c6c;
            cursor: pointer;
          }
        }
      }
    }
  }
</style>
